#include "../include/myhead.h"
#include "../include/client_list.h"
#include "../include/user_list.h"
#include "../include/comm.h"

#define PORT 8100

UserNode *user_head;

ClientNode *client_head;

void user_info_init()
{
    user_head = user_list_init();

    FILE *fp = fopen("/mnt/hgfs/share/chat_server/user_info.txt", "r");
    if(fp == NULL)
    {
        perror("打开user_info.txt失败");
        exit(1);
    }

    char input[200];
    memset(input, 0, sizeof(input));
    while(fgets(input, sizeof(input), fp))
    {
        input[strcspn(input, "\n")] = '\0';
        user_list_insert_tail(user_head, input);
        memset(input, 0, sizeof(input));
    }
    if(ferror(fp))
    {
        printf("读取user_info.txt出错！\n");
        exit(1);
    }

    fclose(fp);
}

int main()
{
    user_info_init();

    int tcpsock, cnt = 0;
    pthread_t pid_recv[10]; 
    pthread_t pid_send;

    client_head = client_list_init();

    pthread_attr_t myattr;
    pthread_attr_init(&myattr);
    pthread_attr_setdetachstate(&myattr, PTHREAD_CREATE_DETACHED);

    struct sockaddr_in bindaddr;
    memset(&bindaddr, 0, sizeof(bindaddr));
    bindaddr.sin_family = AF_INET;
    bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    bindaddr.sin_port = htons(PORT);

    struct sockaddr_in clientaddr;
    memset(&clientaddr, 0, sizeof(clientaddr));
    int size = sizeof(clientaddr);

    tcpsock = socket(AF_INET, SOCK_STREAM, 0);
    if(tcpsock == -1)
    {
        perror("创建套接字失败");
        return 1;
    }

    int on = 1;
    setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    if(bind(tcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
    {
        perror("绑定失败");
        return 1;
    }

    if(listen(tcpsock, 5) == -1)
    {
        perror("监听失败");
        return 1;
    }

    while(1)
    {
        int newsock = accept(tcpsock, (struct sockaddr *)&clientaddr, &size);
        if(newsock == -1)
        {
            perror("接收连接请求失败");
            continue;
        }

        char *ip = inet_ntoa(clientaddr.sin_addr);
        uint16_t port = ntohs(clientaddr.sin_port);

        printf("服务器与套接字为%d，IP为%s，端口号为%hu的客户端连接成功\n", newsock, ip, port);

        ClientNode *new_node = malloc(sizeof(ClientNode));
        if(new_node == NULL)
        {
            printf("客户端链表新结点创建失败\n");
            exit(1);
        }
        memset(new_node->ip, 0, sizeof(new_node->ip));
        memset(new_node->username, 0, sizeof(new_node->username));
        memset(new_node->nickname, 0, sizeof(new_node->nickname));

        new_node->sock = newsock;
        strncpy(new_node->ip, ip, sizeof(new_node->ip));
        new_node->port = port;

        client_list_insert_tail(client_head, new_node);

        show_client(client_head);

        pthread_create(&pid_recv[cnt], &myattr, server_recv, new_node);
        cnt++;
    }
    
    free_client_list(client_head);
    
    close(tcpsock);

    return 0;
}